from app.crud import work_order_crud
from common.database import DatabaseService
from common.exceptions import BizException, ErrorCode
from common.logger import create_logger
from common.base_enums import WorkOrderStatus

logger = create_logger(__name__)


async def create_work_order_from_alarm(
		db: DatabaseService,
		alarm_id: int,
		device_type: str,
		device_id: int,
		description: str,
		operator_code: str
) -> int:
	"""
	从告警创建工单

	Args:
		db: 数据库服务实例
		alarm_id: 告警ID
		device_type: 设备类型
		device_id: 设备ID
		description: 问题描述
		operator_code: 操作人编码

	Returns:
		int: 新创建的工单ID
	"""
	from app.schemas.work_order_schemas import WorkOrderCreate
	from common.base_enums import WorkOrderSourceType, WorkOrderDeviceType, WorkOrderPriority

	try:
		# 构造工单创建数据
		work_order_data = WorkOrderCreate(
			title=f"告警处理-{alarm_id}",
			source_type=WorkOrderSourceType.ALARM,
			alarm_id=alarm_id,
			device_type=WorkOrderDeviceType(device_type),
			device_id=device_id,
			priority=WorkOrderPriority.HIGH,
			description=description
		)

		# 创建工单
		work_order_id = await work_order_crud.create_work_order(db, work_order_data, operator_code)
		return work_order_id
	except Exception as e:
		logger.error(f"从告警创建工单失败: {e}")
		raise BizException.from_error_code(ErrorCode.INTERNAL_SERVER_ERROR, message=f"创建工单失败: {str(e)}")


async def dispatch_work_order(
		db: DatabaseService,
		work_order_id: int,
		assignee_code: str,
		expect_finish_time,
		comment: str,
		operator_code: str
) -> None:
	"""
	分派工单

	Args:
		db: 数据库服务实例
		work_order_id: 工单ID
		assignee_code: 负责人编码
		expect_finish_time: 期望完成时间
		comment: 备注
		operator_code: 操作人编码
	"""
	from app.schemas.work_order_schemas import WorkOrderDispatchRequest

	try:
		# 构造分派数据
		dispatch_data = WorkOrderDispatchRequest(
			assignee_code=assignee_code,
			expect_finish_time=expect_finish_time,
			comment=comment
		)

		# 分派工单
		success = await work_order_crud.dispatch_work_order(db, work_order_id, dispatch_data, operator_code)
		if not success:
			raise BizException.from_error_code(ErrorCode.NOT_FOUND, message="工单不存在")

	except BizException:
		raise
	except Exception as e:
		logger.error(f"分派工单失败: {e}")
		raise BizException.from_error_code(ErrorCode.INTERNAL_SERVER_ERROR, message=f"分派工单失败: {str(e)}")


async def process_work_order(
		db: DatabaseService,
		work_order_id: int,
		comment: str,
		operator_code: str
) -> None:
	"""
	处理工单（接单）

	Args:
		db: 数据库服务实例
		work_order_id: 工单ID
		comment: 备注
		operator_code: 操作人编码
	"""
	from app.schemas.work_order_schemas import WorkOrderProcessRequest

	try:
		# 构造处理数据
		process_data = WorkOrderProcessRequest(
			comment=comment
		)

		# 处理工单
		success = await work_order_crud.process_work_order(db, work_order_id, process_data, operator_code)
		if not success:
			raise BizException.from_error_code(ErrorCode.NOT_FOUND, message="工单不存在")

	except BizException:
		raise
	except Exception as e:
		logger.error(f"处理工单失败: {e}")
		raise BizException.from_error_code(ErrorCode.INTERNAL_SERVER_ERROR, message=f"处理工单失败: {str(e)}")


async def resolve_work_order(
		db: DatabaseService,
		work_order_id: int,
		solution: str,
		comment: str,
		operator_code: str
) -> None:
	"""
	解决工单

	Args:
		db: 数据库服务实例
		work_order_id: 工单ID
		solution: 解决方案
		comment: 备注
		operator_code: 操作人编码
	"""
	from app.schemas.work_order_schemas import WorkOrderResolveRequest

	try:
		# 构造解决数据
		resolve_data = WorkOrderResolveRequest(
			solution=solution,
			comment=comment
		)

		# 解决工单
		success = await work_order_crud.resolve_work_order(db, work_order_id, resolve_data, operator_code)
		if not success:
			raise BizException.from_error_code(ErrorCode.NOT_FOUND, message="工单不存在")

	except BizException:
		raise
	except Exception as e:
		logger.error(f"解决工单失败: {e}")
		raise BizException.from_error_code(ErrorCode.INTERNAL_SERVER_ERROR, message=f"解决工单失败: {str(e)}")


async def close_work_order(
		db: DatabaseService,
		work_order_id: int,
		close_comment: str,
		operator_code: str
) -> None:
	"""
	关闭工单

	Args:
		db: 数据库服务实例
		work_order_id: 工单ID
		close_comment: 关闭说明
		operator_code: 操作人编码
	"""
	from app.schemas.work_order_schemas import WorkOrderCloseRequest
	from common.base_enums import AlarmCloseReason
	# 延迟导入避免循环依赖
	from app.service import alarm_service

	try:
		# 构造关闭数据
		close_data = WorkOrderCloseRequest(
			close_comment=close_comment
		)

		# 关闭工单
		success = await work_order_crud.close_work_order(db, work_order_id, close_data, operator_code)
		if not success:
			raise BizException.from_error_code(ErrorCode.NOT_FOUND, message="工单不存在")

		# 回调告警服务，修改告警事件状态
		# 获取工单信息，检查是否关联了告警
		work_order = await work_order_crud.get_work_order_by_id(db, work_order_id)
		if work_order and work_order.alarm_id:
			# 调用告警服务恢复告警
			await alarm_service.recover_alarm_by_work_order(
				db=db,
				alarm_id=work_order.alarm_id,
				close_reason=AlarmCloseReason.WORK_ORDER_CLOSED,
				operator=operator_code
			)

	except BizException:
		raise
	except Exception as e:
		logger.error(f"关闭工单失败: {e}")
		raise BizException.from_error_code(ErrorCode.INTERNAL_SERVER_ERROR, message=f"关闭工单失败: {str(e)}")


async def auto_close_work_order_by_alarm(
		db: DatabaseService,
		alarm_id: int
) -> bool:
	"""
	系统自动关单（告警恢复时调用）

	Args:
		db: 数据库服务实例
		alarm_id: 告警ID

	Returns:
		bool: 是否成功关闭工单
	"""
	try:
		# 查找关联的工单
		work_order_sql = """
			SELECT wo.id, wo.code, wo.status
			FROM wo_work_order wo
			JOIN am_alarm_work aw ON aw.work_order_id = wo.id
			WHERE aw.alarm_id = %s AND wo.status NOT IN ('CLOSED', 'AUTO_CLOSED')
			LIMIT 1
		"""
		work_order = db.get_one(work_order_sql, (alarm_id,))

		if not work_order:
			logger.info(f"告警 {alarm_id} 没有找到需要关闭的工单")
			return False

		# 自动关闭工单
		update_sql = """
			UPDATE wo_work_order
			SET status = %s, closed_by = %s, closed_at = NOW(),
				close_comment = %s, solution = %s
			WHERE id = %s
		"""
		db.execute(
			update_sql,
			(
				WorkOrderStatus.AUTO_CLOSED.value,
				'SYSTEM',
				'告警已自动恢复，系统自动关闭工单',
				'系统检测到告警恢复，自动关闭',
				work_order['id']
			)
		)

		# 记录工单流转日志
		log_sql = """
			INSERT INTO wo_work_order_log
			(wo_id, action, actor_code, actor_name, comment, old_status, new_status)
			VALUES (%s, %s, %s, %s, %s, %s, %s)
		"""
		db.execute(
			log_sql,
			(
				work_order['id'],
				'AUTO_CLOSE',
				'SYSTEM',
				'系统',
				'告警恢复，系统自动关闭工单',
				work_order['status'],
				WorkOrderStatus.AUTO_CLOSED.value
			)
		)

		logger.info(f"工单 {work_order['code']} 已自动关闭")
		return True

	except Exception as e:
		logger.error(f"自动关闭工单失败: {e}")
		return False
